package cs.upt.awp.controller;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import cs.upt.awp.data.Status;
import cs.upt.awp.data.TravelNote;
import cs.upt.awp.data.TravelRecord;
import cs.upt.awp.model.TravelImageGalleryModel;
import cs.upt.awp.model.TravelRecordViewModel;
import cs.upt.awp.services.CityServices;
import cs.upt.awp.services.CountryServices;
import cs.upt.awp.services.TravelImagesServices;
import cs.upt.awp.services.TravelNotesServices;
import cs.upt.awp.services.TravelRecordsServices;
import cs.upt.awp.services.TravelUsersServices;

@Controller
@RequestMapping("/records")
public class TravelRecordsController {

	@Autowired
	TravelRecordsServices recordsServices;
	
	@Autowired
	CityServices cityServices;
	
	@Autowired
	CountryServices countryServices;
	
	@Autowired
	TravelUsersServices usersServices;
	
	@Autowired
	TravelNotesServices notesServices;
	
	@Autowired
	TravelImagesServices imagesServices;
	
	@InitBinder
    public void initBinder(WebDataBinder binder) {
        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
        sdf.setLenient(true);
        binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, true));
    }
	
	@RequestMapping(value="/add", method=RequestMethod.POST, consumes=MediaType.APPLICATION_JSON_VALUE)
	public @ResponseBody Status addRecord(@RequestBody TravelRecord record){
		try {
			recordsServices.addEntity(record);
			return new Status(1,"Record successfully added!");
		} catch (Exception e) {
			//e.printStackTrace();
			return new Status(0,"Error: "+e);
		}
		
	}
	
	@RequestMapping(value = "/addrecord", method = RequestMethod.GET)
	public ModelAndView addRecordGET(HttpServletRequest request) {

		ModelAndView model = new ModelAndView();				
		model.addObject("travelRecord", new TravelRecordViewModel());
		model.setViewName("addRecord");

		return model;

	}
	
	@RequestMapping(value = "/addrecord", method = RequestMethod.POST)
	public String addRecordPOST(@ModelAttribute("travelRecord") TravelRecordViewModel travelRecord, HttpServletRequest request){
		ModelAndView model = new ModelAndView();
		try {
			
			Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		    String name = auth.getName(); //get logged in username
		
		    TravelRecord tr = new TravelRecord();
		    
		    tr.setCity(cityServices.getEntityById(Long.parseLong(travelRecord.getCity())));
		    tr.setCountry(countryServices.getEntityById(travelRecord.getCountry()));
		    tr.setUser(usersServices.findByUserName(name));
		    tr.setStartDate(travelRecord.getStartDate());
		    tr.setEndDate(travelRecord.getEndDate());

		    
			tr.setDate(new Date());
			recordsServices.addEntity(tr);
		} catch (Exception e) {
			model.addObject("error", e.getMessage());		
		}
		return "redirect:/records/myrecords/";
		
	}
	
	@RequestMapping(value = "/updaterecord/{id}", method = RequestMethod.GET)
	public ModelAndView updateRecordGET(@PathVariable("id") long id, HttpServletRequest request) throws Exception {

		ModelAndView model = new ModelAndView();
		TravelRecord travelRecord = recordsServices.getEntityById(id);
		TravelRecordViewModel vmodel = new TravelRecordViewModel();
		vmodel.setCity(travelRecord.getCity().getId().toString());
		vmodel.setCountry(travelRecord.getCountry().getCode());
		vmodel.setStartDate(travelRecord.getStartDate());
		vmodel.setEndDate(travelRecord.getEndDate());
		vmodel.setId(travelRecord.getId());
		
		//get notes for this record
		List<TravelNote> notes = new ArrayList<TravelNote>();
		notes = notesServices.getRecordNotes(id);
		List<TravelImageGalleryModel> images = imagesServices.getImagesForRecord(id);
		model.addObject("notes", notes);
		model.addObject("images", images);
		model.addObject("travelRecord", vmodel);
		model.setViewName("editRecord");

		return model;

	}
	
	@RequestMapping(value = "/updaterecord/{id}", method = RequestMethod.POST)
	public String updateRecordPOST(@PathVariable("id") long id, @ModelAttribute("travelRecord") TravelRecordViewModel travelRecord){
		ModelAndView model = new ModelAndView();
		try {
			
			//Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		    //String name = auth.getName(); //get logged in username
		    
		    TravelRecord tr = recordsServices.getEntityById(id);
		    System.out.println(id);
		    tr.setCity(cityServices.getEntityById(Long.parseLong(travelRecord.getCity())));
		    System.out.println("City:" + id);
		    tr.setCountry(countryServices.getEntityById(travelRecord.getCountry()));
		    tr.setStartDate(travelRecord.getStartDate());
		    tr.setEndDate(travelRecord.getEndDate());


			recordsServices.updateEntity(tr);
		} catch (Exception e) {
			model.addObject("error", e.getMessage());		
		}
		model.addObject("travelRecord", travelRecord);
		model.setViewName("editRecord");
		return "redirect:/records/myrecords/";
	}
	
	@RequestMapping(value = "/myrecords", method = RequestMethod.GET)
	public ModelAndView getMyRecrds(HttpServletRequest request) {
		
		List<TravelRecord> recordList = new ArrayList<TravelRecord>();
		try {
			//recordList = recordsServices.getEntityList();			
			recordList = recordsServices.getUserRecords(request.getRemoteUser().toString());

		} catch (Exception e) {
			e.printStackTrace();
		}
		
		ModelAndView model = new ModelAndView();
		
		model.addObject("records", recordList);
		model.setViewName("myRecords");

		return model;

	}
	
	@RequestMapping(value="/{id}", method=RequestMethod.GET)
	public @ResponseBody TravelRecord getTravelRecord(@PathVariable("id") long id){
		TravelRecord record = null;
		try {
			record = recordsServices.getEntityById(id);
		} catch (Exception e) {		
			e.printStackTrace();
		}
		return record;
	}	
	
	@RequestMapping(value="/{user}/list", method=RequestMethod.GET)
	public @ResponseBody List<TravelRecord> getUserRecords(@PathVariable("user") String user){
		try {
			return recordsServices.getUserRecords(user);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new ArrayList<TravelRecord>();
	}
	
	@RequestMapping(value="/delete/{id}", method=RequestMethod.GET)
	public String deleteTravelRecord(@PathVariable("id") long id){
		System.out.println("record id: "+ id);
		try{
			
			List<TravelNote> notes = notesServices.getRecordNotes(id);
			
			//remove all notes
			if(notes!=null && !notes.isEmpty()){
				for(int i=0; i < notes.size(); i++)
					notesServices.deleteEntity(notes.get(i).getId());
			}

			//remove all images
			List<TravelImageGalleryModel> images = imagesServices.getImagesForRecord(id);
			if(images!=null && !images.isEmpty()){
			for(int i=0; i < images.size(); i++)
				imagesServices.deleteEntity(images.get(i).getId());
			}
			//remove the record
			recordsServices.deleteEntity(id);
		}catch(Exception e){
			e.printStackTrace();
		}
		return "redirect:/records/myrecords";
	}

	@RequestMapping(value="/map", method=RequestMethod.GET)
	public @ResponseBody ModelAndView getRecordsMap(HttpServletRequest request){		
		ModelAndView model = new ModelAndView();
		model.addObject("username", request.getRemoteUser().toString());
		model.setViewName("recordsMap");
		return model;
	}
}
